package com.industrial.premu.ann.aop;

import cn.hutool.core.util.ArrayUtil;
import com.industrial.common.security.utils.SecurityUtils;
import com.industrial.premu.ann.BuilderVo;
import com.industrial.premu.dto.PreMuChartsDto;
import com.industrial.premu.vo.PreMuChartsVo;
import com.industrial.system.api.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

@Slf4j
@Aspect
@Component
public class BuilderAspect {

    @Pointcut("@annotation(com.industrial.premu.ann.BuilderVo)")
    public void pointcut(){

    }


    private Method getMethod(JoinPoint joinPoint) throws NoSuchMethodException {
        // 获取目标方法的签名
        String methodName = joinPoint.getSignature().getName();
        // 获取目标方法的参数类型
        Class[] parameterTypes = ((org.aspectj.lang.reflect.MethodSignature) joinPoint.getSignature()).getParameterTypes();
        // 获取目标类
        Class targetClass = joinPoint.getTarget().getClass();
        // 获取目标方法
        return targetClass.getMethod(methodName, parameterTypes);
    }

    @Before("pointcut()")
    public void around(JoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Map<String, String[]> parameterMap = request.getParameterMap();

        Method method = getMethod(joinPoint);
        // 获取方法上的注解
        BuilderVo builderVo = method.getAnnotation(BuilderVo.class);
        String[] require = builderVo.require();

        for(int i = 0;i<require.length;i++){
            String s = require[i];
            if(!parameterMap.containsKey(s)){
                throw new RuntimeException(String.format("未找到必须绑定的参数%s,请检查传参",s));
            }
        }

        //只支对指标分析中的接口
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if(arg instanceof PreMuChartsDto){
                Field years = arg.getClass().getDeclaredField("years");
                String[] years1 = parameterMap.get("years");
                if(years1.length > 1){
                    throw new RuntimeException("找到了多个Years值");
                }
                years.setAccessible(true);
                years.set(arg,parameterMap.get("years")[0]);
                years.setAccessible(false);
                Set<String> roles = SecurityUtils.getLoginUser().getRoles();
                if(roles != null && !roles.isEmpty()){
                    if(ArrayUtil.containsAny(roles.toArray(),"x_01_011","along_yellow_river")){
                        Field county = arg.getClass().getDeclaredField("county");
                        county.setAccessible(true);
                        county.set(arg,SecurityUtils.getLoginUser().getSysUser().getDistrict());
                        county.setAccessible(false);

                    } else if (ArrayUtil.contains(roles.toArray(),"s_01_011")) {
                        Field city = arg.getClass().getDeclaredField("city");
                        city.setAccessible(true);
                        city.set(arg,SecurityUtils.getLoginUser().getSysUser().getCity());
                        city.setAccessible(false);
                    }else if(ArrayUtil.contains(roles.toArray(),"p_01_011")){
                        Field province = arg.getClass().getDeclaredField("province");
                        province.setAccessible(true);
                        province.set(arg,SecurityUtils.getLoginUser().getSysUser().getProvince());
                        province.setAccessible(false);
                    }
                }

                String[] companyTypeArgs = parameterMap.get("companyType");
                if(companyTypeArgs.length > 1){
                    throw new RuntimeException("找到了多个companyType值");
                }
                String companyType = parameterMap.get("companyType")[0];
                Field companyTypeField = arg.getClass().getDeclaredField("companyType");
                companyTypeField.setAccessible(true);
                companyTypeField.set(arg,companyType);
                companyTypeField.setAccessible(false);
            }
        }
    }
}
